package com.cgnpc.scp.achievement.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cgnpc.cud.core.domain.AjaxResult;
import com.cgnpc.cuddemo.utils.IDHelper;
import com.cgnpc.framework.userinfo.CurrentUser;
import com.cgnpc.scp.achievement.mybatis.entity.*;
import com.cgnpc.scp.achievement.mybatis.mapper.client.AwardFileMapper;
import com.cgnpc.scp.achievement.mybatis.mapper.client.AwardMapper;
import com.cgnpc.scp.achievement.mybatis.mapper.client.AwardUserMapper;
import com.cgnpc.scp.achievement.pojo.AwardDetail;
import com.cgnpc.scp.achievement.pojo.SaveAwardReq;
import com.cgnpc.scp.achievement.service.AwardService;
import com.cgnpc.scp.common.bean.CreateFileInfo;
import com.cgnpc.scp.common.bean.MyPageResult;
import com.cgnpc.scp.common.pojo.UserInfo;
import com.cgnpc.scp.common.service.ExcelCustomTemplateService;
import com.cgnpc.scp.common.utils.*;
import com.cgnpc.scp.manager.mybatis.entity.DataDict;
import com.cgnpc.scp.manager.service.IDataDictService;
import org.apache.ibatis.session.SqlSession;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import java.io.InputStream;
import java.util.*;

@Service
public class AwardServiceImpl implements AwardService
{
    private static final Logger LOGGER = LoggerFactory.getLogger(AwardServiceImpl.class);

    @Autowired
    private CurrentUser currentUser;

    @Autowired
    private AwardMapper awardMapper;

    @Autowired
    private AwardUserMapper awardUserMapper;

    @Autowired
    private AwardFileMapper awardFileMapper;
    @Autowired
    private ExcelCustomTemplateService excelCustomTemplateService;

    @Autowired
    private SqlSession sqlSession;

    @Autowired
    private IDataDictService dataDictService;
    @Override
    public AwardDetail saveAward(SaveAwardReq req) {
        AwardDetail re = null;

        try {
            boolean isNew = false;
            UserInfo userinfo = currentUser.getCurrentUserDetail();
            Award award = req.getAward();
            if (award.getId() == null) {
                award.setId(IDHelper.uuid());
                award.setCreateUser(userinfo.getUserId());
                award.setCreateUserName(userinfo.getUserName());

                //awardMapper.insertSelective(award);
                awardMapper.insert(award);

                isNew = true;
            }else {
                award.setLastUpdateTime(new Date());
                award.setLastUpdateUser(userinfo.getUserId());
                award.setLastUpdateUserName(userinfo.getUserName());

                //awardMapper.updateByPrimaryKeySelective(award);
                awardMapper.updateById(award);
            }

            List<AwardUser> awardUsers = req.getAwardUsers();
            if (!isNew) {
               /* AwardUserExample example = new AwardUserExample();
                AwardUserExample.Criteria criteria = example.createCriteria();
                criteria.andAwardIdEqualTo(award.getId());
                awardUserMapper.deleteByExample(example);*/
                QueryWrapper<AwardUser> queryWrapper = new QueryWrapper();
                queryWrapper.eq("award_id", award.getId());
                awardUserMapper.delete(queryWrapper);
            }
            for (AwardUser curData : awardUsers) {
                curData.setId(IDHelper.uuid());
                curData.setAwardId(award.getId());
                //awardUserMapper.insertSelective(curData);
                awardUserMapper.insert(curData);
            }

            List<AwardFile> awardFiles = req.getAwardFiles();
            if (!isNew) {
                /*AwardFileExample example = new AwardFileExample();
                AwardFileExample.Criteria criteria = example.createCriteria();
                criteria.andAwardIdEqualTo(award.getId());
                awardFileMapper.deleteByExample(example);*/
                QueryWrapper<AwardFile> queryWrapper = new QueryWrapper();
                queryWrapper.eq("award_id", award.getId());
                awardFileMapper.delete(queryWrapper);
            }
            for (AwardFile curData : awardFiles) {
                curData.setId(IDHelper.uuid());
                curData.setAwardId(award.getId());
                awardFileMapper.insert(curData);
            }
            re = new AwardDetail();
            re.setAward(award);
            re.setAwardUsers(awardUsers);
            re.setAwardFiles(awardFiles);
        } catch (Exception e) {
            LOGGER.error("AwardServiceImpl save failed:", e);
        }


        return re;
    }

    @Override
    public AwardDetail getAwardById(String id) {
        AwardDetail re = null;

        //Award award = awardMapper.selectByPrimaryKey(id);
        Award award = awardMapper.selectById(id);
        if (award != null) {
            re = new AwardDetail();
            re.setAward(award);

            /*AwardUserExample userExample = new AwardUserExample();
            AwardUserExample.Criteria userCriteria = userExample.createCriteria();
            userCriteria.andAwardIdEqualTo(award.getId());
            List<AwardUser> awardUsers = awardUserMapper.selectByExample(userExample);*/
            QueryWrapper<AwardUser> queryWrapper = new QueryWrapper();
            queryWrapper.eq("award_id", award.getId());
            List<AwardUser> awardUsers = awardUserMapper.selectList(queryWrapper);
            re.setAwardUsers(awardUsers);

            /*AwardFileExample fileExample = new AwardFileExample();
            AwardFileExample.Criteria fileCriteria = fileExample.createCriteria();
            fileCriteria.andAwardIdEqualTo(award.getId());
            List<AwardFile> knowledgeFiles = awardFileMapper.selectByExample(fileExample);*/
            QueryWrapper<AwardFile> queryWrapper2 = new QueryWrapper();
            queryWrapper2.eq("award_id", award.getId());
            List<AwardFile> knowledgeFiles = awardFileMapper.selectList(queryWrapper2);
            re.setAwardFiles(knowledgeFiles);
        }

        return re;
    }

    @Override
    public MyPageResult<Award> queryAwardPageList(Award req) {
        MyPageResult<Award> re = null;

        int pageNum = req.getPageNum();
        int pageSize = req.getPageSize();
        Page<Award> queryPage = new Page<>(pageNum, pageSize);

        /*AwardExample example = new AwardExample();
        AwardExample.Criteria criteria = example.createCriteria();
        criteria.andAwardCodeLike(SqlUtil.valueJoinLikeBoth(req.getAwardCode()));
        List<Award> awards = awardMapper.selectByExample(example);
        PageInfo<Award> pageResult = new PageInfo<>(queryPage.getResult());
        */
        QueryWrapper<Award> queryWrapper = new QueryWrapper();
        if(req.getAwardCode() != null){
            queryWrapper.like("award_code", req.getAwardCode());
        }
        if (req.getYear() != null) {
            queryWrapper.like("year", req.getYear());
        }

        IPage<Award> awardPageInfo = awardMapper.selectPage(queryPage, queryWrapper);

        re = MyPageResultUtil.createMyPageResultPlus(awardPageInfo);

        return re;
    }

    @Override
    public boolean delByIds(List<String> ids) {
        boolean re = false;

        /*AwardExample example = new AwardExample();
        AwardExample.Criteria criteria = example.createCriteria();
        criteria.andIdIn(ids);
        awardMapper .deleteByExample(example);*/

        awardMapper.deleteBatchIds(ids);
        re = true;

        return re;
    }
    @Override
    public <T extends Award> CreateFileInfo exportExcel(T reqEntity) throws Exception{
        final String logInfo = "[exportExcel_UUID_" + UUID.randomUUID() + "]";
        CreateFileInfo createFileInfo = null;

        try {
            // 创建queryExample
            AwardExample awardExample = createQueryExample(reqEntity);
            // mappedStatementNamespace为mybatis生成的mapper.xml中的命名空间
            String mappedStatementNamespace = "com.cgnpc.scp.achievement.mybatis.mapper.client.AwardMapper";
            // mappedStatementMethod为mybatis生成的mapper.xml中的方法
            String mappedStatementMethod = "selectByExampleWithCustom";
            // mappedStatementId为具体指向的方法
            String mappedStatementId = mappedStatementNamespace + "." + mappedStatementMethod;

            // mappedStatementParameter可以为mybatis自动生成的XxxExample实体类，例如UserExample
            Object mappedStatementParameter = awardExample;
            //数字字典固定的值==Award_exportExcel
            //String exportDictGroupKey = DataDictUtil.DICT_GROUP_KEY_WITH_CAPACITY_EXPORTEXCEL;
            String exportDictGroupKey = "Award_exportExcel";
            createFileInfo = excelCustomTemplateService.createXlsxToWebDir(
                    sqlSession
                    , mappedStatementId
                    , mappedStatementParameter
                    , exportDictGroupKey
            );
        } catch (Exception e) {
            LOGGER.error("{}error;", logInfo, e);
            throw e;
        }

        return createFileInfo;
    }
    /**
     * 创建查询Example
     *
     * @param reqEntity reqEntity
     * @param <T>       T
     * @return Example
     */
    private <T extends Award> AwardExample createQueryExample(T reqEntity) {
        // mybatis查询方式
        AwardExample awardExample = new AwardExample();
        // 设置排序字段
        // queryExample.setOrderByClause("order_index");
        // 设置查询条件
        // 项目代码
        // 项目名称
        // 勾选项目----多个id
        if (ListUtil.getListSizeWith0(reqEntity.getIds()) > 0) {
            // queryExampleCriteria.andProjectNameLike(SqlUtil.valueJoinLikeBoth(reqEntity.getProjectName()));
            // addCriterion("project_name like", value, "projectName");
            awardExample.setIds(reqEntity.getIds());
        }
        return awardExample;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public <T extends Award> AjaxResult importFromExcel(UserInfo loginUserInfo, Locale reqLocale, MultipartHttpServletRequest request) throws Exception {
        final String logInfo = "[importFromExcel_UUID_" + UUID.randomUUID() + "]";
        AjaxResult ajaxResult = null;
        XSSFWorkbook workbook = null;
        InputStream reqFileInputStream = null;
        MultipartFile reqFile = request.getFile("file");
        try {
            if (reqFile == null) {
                return AjaxResultUtil.createErrorMessage("文件不存在");
            }

            boolean reqFileEmpty = reqFile.isEmpty();
            String reqFileName = reqFile.getName();
            String reqFileOriginalFilename = reqFile.getOriginalFilename();

            LOGGER.info("{}reqFileEmpty:{};reqFileName:{};reqFileOriginalFilename:{};"
                    , logInfo
                    , reqFileEmpty, reqFileName, reqFileOriginalFilename
            );

            if (!reqFileOriginalFilename.toLowerCase().endsWith(".xlsx")) {
                LOGGER.error("{}只支持.xlsx文件。", logInfo);
                return AjaxResultUtil.createErrorMessage("只支持.xlsx文件", null);
            }

            reqFileInputStream = reqFile.getInputStream();
            workbook = new XSSFWorkbook(reqFileInputStream);
            Sheet sheet = workbook.getSheetAt(0);

            Iterator<Row> itRow = sheet.rowIterator();
            int rowIndex = 0;
            Row row = null;
            Cell cell000 = null;
            Cell cell001 = null;
            Cell cell002 = null;
            Cell cell003 = null;
            Cell cell004 = null;
            Cell cell005 = null;
            Cell cell006 = null;
            Cell cell007 = null;
            String cellValue000 = null;
            String cellValue001 = null;
            String cellValue002 = null;
            String cellValue003 = null;
            String cellValue004 = null;
            String cellValue005 = null;
            String cellValue006 = null;
            String cellValue007 = null;

            final List<T> reqEntityList = new ArrayList<>();
            T reqEntity = null;

            while (itRow.hasNext()) {
                row = itRow.next();

                // 第1行为标题
                if (rowIndex++ <= 0) {
                    continue;
                }

                // 获奖名称0
                // 授权单位1
                // 级别2
                // 获奖年度3
                // 专业分部名称4
                // 负责人5
                // 完成人员6
                cell000 = row.getCell(0);
                cell001 = row.getCell(1);
                cell002 = row.getCell(2);
                cell003 = row.getCell(3);
                cell004 = row.getCell(4);
                cell005 = row.getCell(5);
                cell006 = row.getCell(6);
                cell007 = row.getCell(7);
                cellValue000 = ExcelUtil.getCellValue(cell000);
                cellValue001 = ExcelUtil.getCellValue(cell001);
                cellValue002 = ExcelUtil.getCellValue(cell002);
                cellValue003 = ExcelUtil.getCellValue(cell003);
                cellValue004 = ExcelUtil.getCellValue(cell004);
                cellValue005 = ExcelUtil.getCellValue(cell005);
                cellValue006 = ExcelUtil.getCellValue(cell006);
                cellValue007 = ExcelUtil.getCellValue(cell007);
                reqEntity = (T) new Award();
                reqEntityList.add(reqEntity);

                // project_code 知识产权名称0
                reqEntity.setAwardCode(cellValue000);
                // project_name 授权单位1
                reqEntity.setAuthorization(cellValue001);
                //reqEntity.setAwardType(cellValue001);
                //intellectual_property_type 级别2
                List<DataDict> dataDictslevel = dataDictService.queryByDictGroupKey("technology_award_level");
                for (DataDict dataDict : dataDictslevel) {
                    if (dataDict.getDictKey().equals(cellValue002)){
                        reqEntity.setLevel(dataDict.getDictText());
                    }
                }
                if (reqEntity.getLevel() == ""){
                    return AjaxResultUtil.createErrorMessage("科学奖的级别不可以为空或者数字字典不存在", null);
                }
                //reqEntity.setLevel(cellValue002);
                // description 获得年份3
                reqEntity.setYear(NumberUtil.parseStringToIntegerWithNull(cellValue003));
                //NumberUtil.parseStringToIntegerWithNull(cellValue007)
                //DateUtil.parseToDate(sdfYyyymmddHhmmss, sdfYyyymmdd, cellValue009)
                // dept_name 专业分部名称4
                reqEntity.setDeptName(cellValue004);
                // dept_id 数字字典===专业分部
                List<DataDict> dataDicts = dataDictService.queryByDictGroupKey("achievement_profession_dept");
                for (DataDict dataDict : dataDicts) {
                    if (dataDict.getDictText().equals(cellValue004)){
                        reqEntity.setDeptId(dataDict.getId());
                    }
                }
                //专业分部
                if(reqEntity.getDeptId() == "" ){
                    throw new RuntimeException("achievement_profession_dept,Value for condition cannot be null");
                }
                // Award_user 负责人
                reqEntity.setPrincipalUser(cellValue005);
                // InventUser 发明人4
                reqEntity.setFinishUser(cellValue006);
                // Acceptance    获奖证书
                reqEntity.setFileName(cellValue007);
                if (ListUtil.getListSizeWith0(reqEntityList) >= SqlUtil.INSERT_BATCH_MAX_ROWS) {
                    saveOrUpdate(loginUserInfo, reqLocale, reqEntityList);
                    reqEntityList.clear();
                }
            }

            if (ListUtil.getListSizeWith0(reqEntityList) > 0) {
                saveOrUpdate(loginUserInfo, reqLocale, reqEntityList);
                reqEntityList.clear();
            }
            ajaxResult = AjaxResultUtil.createSuccessMessage("保存成功");
        } catch (Exception e) {
            LOGGER.error("{}error;", logInfo, e);
            throw e;
        } finally {
            IOUtil.closeStream(reqFileInputStream);
            ExcelUtil.closeWorkbook(workbook);
        }

        return ajaxResult;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public <T extends Award> AjaxResult saveOrUpdate(UserInfo loginUserInfo, Locale reqLocale, List<T> reqEntityList) {
        final String logInfo = "[PurchaseProject_saveOrUpdate_UUID_" + UUID.randomUUID() + "]";
        AjaxResult ajaxResult = null;

        try {
            Date nowDate = new Date();

            // begin 获取登录用户的信息
            String loginUserInfoUserId = loginUserInfo.getUserId();
            String loginUserInfoUserName = loginUserInfo.getUserName();
            // end 获取登录用户的信息

            //PurchaseProject dbPurchaseProject = null;
            Award usedEntity = null;
            int saveRows = 0;
            int updateRows = 0;

            String reqId = null;
            String reqProjectCode = null;

            for (Award reqEntity : reqEntityList) {
                reqId = reqEntity.getId();
                reqProjectCode = reqEntity.getAwardCode();

                // dbPurchaseProject = purchaseProjectMapper.selectByPrimaryKey(reqId);

                if (StringUtil.isNullOrSpace(reqId)) {
                    // 保存
                    usedEntity = new Award();
                    usedEntity.setId(IDHelper.uuidNew());
                    usedEntity.setAwardCode(reqProjectCode);
                    usedEntity.setAuthorization(reqEntity.getAuthorization());
                    usedEntity.setYear(reqEntity.getYear());
                    usedEntity.setLevel(reqEntity.getLevel());
                    usedEntity.setDeptId(reqEntity.getDeptId());
                    usedEntity.setDeptName(reqEntity.getDeptName());
                    usedEntity.setPrincipalUser(reqEntity.getPrincipalUser());
                    usedEntity.setFinishUser(reqEntity.getFinishUser());
                    usedEntity.setCreateTime(nowDate);
                    usedEntity.setCreateUser(loginUserInfoUserId);
                    usedEntity.setCreateUserName(loginUserInfoUserName);
                    usedEntity.setLastUpdateTime(nowDate);
                    usedEntity.setLastUpdateUser(loginUserInfoUserId);
                    usedEntity.setLastUpdateUserName(loginUserInfoUserName);
                    saveRows += awardMapper.insert(usedEntity);
                } else {
                    // 修改
                    usedEntity = new Award();
                    usedEntity.setId(reqId);
                    usedEntity.setAwardCode(reqProjectCode);
                    usedEntity.setAuthorization(reqEntity.getAuthorization());
                    usedEntity.setYear(reqEntity.getYear());
                    // usedEntity.setCreateTime(nowDate);
                    // usedEntity.setCreateUser(loginUserInfoUserId);
                    // usedEntity.setCreateUserName(loginUserInfoUserName);
                    usedEntity.setLastUpdateTime(nowDate);
                    usedEntity.setLastUpdateUser(loginUserInfoUserId);
                    usedEntity.setLastUpdateUserName(loginUserInfoUserName);

                    updateRows += awardMapper.updateById(usedEntity);
                }
            }

            String strResultInfo = "保存" + saveRows + "行；修改" + updateRows + "行；";

            ajaxResult = AjaxResultUtil.createSuccessMessage(strResultInfo);
        } catch (Exception e) {
            LOGGER.error("{}saveOrUpdate.error;", logInfo, e);
            throw e;
        }

        return ajaxResult;
    }
}
